﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Rappelz.GameServer
{
    public class FieldPropManager : SchedulerObject, FieldProp.IFieldPropDeleteHandler
    {
        /// <summary>
        /// The instance!
        /// </summary>
        protected static FieldPropManager m_instance;

        /// <summary>
        /// Returns the instance
        /// </summary>
        public static FieldPropManager Instance
        {
            get { return m_instance; }
        }

        public static bool Init()
        {
            FieldPropManager.m_instance = new FieldPropManager();

            RappelzServer.Instance.SetObjectPriority(FieldPropManager.m_instance, SchedulerObject.Priority.Normal);
            return true;
        }

// UserDefinedType: FieldPropManager
// 
// BaseClass      :   StructFieldProp::FieldPropDeleteHandler, offset = 0x40
// VTable         :     , Type:  *
        public void onFieldPropDelete(FieldProp prop)
        {
//             if (prop.m_pFieldPropBase.nLifeTime != 0)
//             {
                lock(this.m_vExpireObject)
                {
                    for(int i = this.m_vExpireObject.Count-1; i >= 0; --i)
                    {
                        FieldProp fp = this.m_vExpireObject[i];
                        if(fp.IsSameObject(prop))
                        {
                            this.m_vExpireObject.RemoveAt(i);
                            break;
                        }
                    }

                }
//            }

            if(!prop.m_PropInfo.bOnce)
            {
                lock (this.m_vRespawnList)
                {
                    GameContent.RegenInfo ri = new GameContent.RegenInfo(prop.m_pFieldPropBase.nRegenTime + Globals.GetArTime(), (uint)prop.nLifeTime);
                    ri.pRespawnInfo = prop.m_PropInfo;
                    this.m_vRespawnList.Add(ri);
                }
            }
        }
// Function       :     public void FieldPropDeleteHandler(const struct StructFieldProp::FieldPropDeleteHandler &)
// Function       :     public void FieldPropDeleteHandler()
// Function       :     public struct StructFieldProp::FieldPropDeleteHandler & operator=(const struct StructFieldProp::FieldPropDeleteHandler &)
// 
// Function       :   public void FieldPropManager::~FieldPropManager()

        public override void onProcess(int nThreadIdx)
        {
// .text:00488338 _lock           = ArcadiaAutoLock ptr -3Ch
            List<GameContent.RegenInfo> vRegenInfo = new List<GameContent.RegenInfo>();
            List<FieldProp> vDeleteList = new List<FieldProp>();
            uint ct;
            FieldProp pProp;
            RLock rl;
            AutoLock al;


            ct = Globals.GetArTime();

            lock(this)
            {
                for(int i = this.m_vRespawnList.Count-1; i >= 0; --i)
                {
                    GameContent.RegenInfo regen = this.m_vRespawnList[i];
                    if (regen.tNextRegen < ct)
                    {
                        vRegenInfo.Add(regen);
                        this.m_vRespawnList.RemoveAt(i);
                    }
                }
            }

            if (vRegenInfo.Count > 0)
            {
                foreach (GameContent.RegenInfo rg in vRegenInfo)
                {
                    rl = RappelzServer.Instance._Lock((uint)(rg.pRespawnInfo.x/GameContent.g_nRegionSize),(uint)(rg.pRespawnInfo.y/GameContent.g_nRegionSize));
                    al = new AutoLock(rl.handle);

                    pProp = FieldProp.Create(this, rg.pRespawnInfo, rg.nLifeTime);
                    if (pProp.nLifeTime != 0)
                    {
                        lock(this.m_vExpireObject)
                        {
                            this.m_vExpireObject.Add(pProp);
                        }
                    }
//                    ArcadiaAutoLock::_ArcadiaAutoLock((v2 - 60));
                }
            }

            lock(this.m_vExpireObject)
            {
                foreach (FieldProp fp in this.m_vExpireObject)
                {
                    if (fp.m_nRegenTime + fp.nLifeTime < ct)
                    {
                        vDeleteList.Add(fp);
                    }
                }
            }

            if (vDeleteList.Count > 0)
            {
                foreach (FieldProp fp in vDeleteList)
                {
                    rl = RappelzServer.Instance._Lock((uint)(fp.m_PropInfo.x/GameContent.g_nRegionSize),(uint)(fp.m_PropInfo.y/GameContent.g_nRegionSize));
                    al = new AutoLock(rl.handle);
                    if (fp.bIsInWorld && !fp.bIsDeleteRequested)
                    {
                        RappelzServer.Instance.RemoveObject(fp);
                        RappelzServer.Instance.DeleteObject(fp);
                    }
//                    ArcadiaAutoLock::_ArcadiaAutoLock((v2 - 80));
                }
            }
        }
// Function       :   public static struct FieldPropManager & FieldPropManager::GetInstance()
// Function       :   public bool FieldPropManager::Init()
// Function       :   public bool DeInit()
        public void RegisterFieldProp(GameContent.FieldPropRespawnInfo prop)
        {
            List<byte> vLayers = new List<byte>();
            GameContent.FieldPropRespawnInfo pPropInfo;
            int nPropId;

            lock(this)
            {
                nPropId = prop.nPropId;
                if (this.m_hsFieldPropId.ContainsKey((uint)nPropId))
                {
                    vLayers.Clear();
                    ChannelManager.GetLayersOfChannel(ChannelManager.GetChannelId(prop.x, prop.y), ref vLayers);
                    foreach (byte layer in vLayers)
                    {
                        pPropInfo = new GameContent.FieldPropRespawnInfo(prop);
                        pPropInfo.nPropId = nPropId;
                        pPropInfo.layer = layer;
                        this.m_vRespawnInfo.Add(pPropInfo);

                        FieldPropBase fpb = this.GetFieldPropBase(pPropInfo.nPropId);
                        GameContent.RegenInfo ri = new GameContent.RegenInfo(fpb.nRegenTime + Globals.GetArTime(), fpb.nLifeTime);
                        ri.pRespawnInfo = pPropInfo;
                        this.m_vRespawnList.Add(ri);
                    }
                }
            }
        }

        public void SpawnFieldPropFromScript(GameContent.FieldPropRespawnInfo prop, int lifeTime)
        {
            lock (this)
            {
                if (this.m_hsFieldPropId.ContainsKey((uint)prop.nPropId))
                {
                    this.m_vRespawnInfo.Add(prop);

                    FieldPropBase fpb = this.GetFieldPropBase(prop.nPropId);
                    GameContent.RegenInfo ri = new GameContent.RegenInfo(0, (uint)lifeTime);
                    ri.pRespawnInfo = prop;
                    this.m_vRespawnList.Add(ri);
                }
            }
        }

// Function       :   public void FieldPropManager::RegisterFieldPropSwitchingData(const struct FieldPropSwitchingData &)
// Function       :   public unsigned int GetFieldPropSwitchingDataCount()

        public void RegisterFieldPropBase(FieldPropBase fpb)
        {
            if(!this.m_hsFieldPropId.ContainsKey(fpb.nPropId))
            {
                this.m_hsFieldPropId.Add(fpb.nPropId, fpb);
            }
        }

        public FieldPropBase GetFieldPropBase(int nPropId)
        {
            if(this.m_hsFieldPropId.ContainsKey((uint)nPropId))
                return this.m_hsFieldPropId[(uint)nPropId];
            return null;
        }
// Function       :   public void FieldPropManager(const struct FieldPropManager &)
// Function       :   protected void FieldPropManager::FieldPropManager()

// Data           :   this+0x44, Member, Type: class std::vector<FieldPropBase,std::allocator<FieldPropBase> >, m_vFieldPropBase
// Data           :   this+0x54, Member, Type: class std::vector<FieldPropSwitchingData,std::allocator<FieldPropSwitchingData> >, m_vFieldPropSwitching
        Dictionary<uint, FieldPropBase> m_hsFieldPropId = new Dictionary<uint, FieldPropBase>();
        List<GameContent.FieldPropRespawnInfo> m_vRespawnInfo = new List<GameContent.FieldPropRespawnInfo>();// Data           :   this+0x80, Member, Type: class std::vector<GameContent::FIELD_PROP_RESPAWN_INFO *,std::allocator<GameContent::FIELD_PROP_RESPAWN_INFO *> >, 
// Data           :   this+0x90, Member, Type: class XCriticalSection, m_CS
        List<GameContent.RegenInfo> m_vRespawnList = new List<GameContent.RegenInfo>();// Data           :   this+0xD0, Member, Type: class std::vector<GameContent::REGEN_INFO,std::allocator<GameContent::REGEN_INFO> >, 
// Data           :   this+0xE0, Member, Type: class XCriticalSection, m_ExpireCS
        List<FieldProp> m_vExpireObject = new List<FieldProp>();// Data           :   this+0x120, Member, Type: class std::vector<StructFieldProp *,std::allocator<StructFieldProp *> >, 

// 
// Function       :   public struct FieldPropManager & operator=(const struct FieldPropManager &)
// Function       :   public void __local_vftable_ctor_closure()
// Function       :   public void * __vecDelDtor(unsigned int)

    }
}
